package com.demo.config.watermark;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfGState;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfStamper;
import com.microsoft.schemas.office.office.CTLock;
import com.microsoft.schemas.vml.*;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.wp.usermodel.HeaderFooterType;
import org.apache.poi.xssf.usermodel.XSSFRelation;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.apache.poi.xwpf.model.XWPFHeaderFooterPolicy;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.apache.poi.xwpf.usermodel.XWPFHeader;
import org.apache.poi.xwpf.usermodel.XWPFParagraph;
import org.apache.xmlbeans.XmlObject;
import org.openxmlformats.schemas.officeDocument.x2006.sharedTypes.STTrueFalse;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.*;

import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.stream.Stream;

/**
 * 各个格式加水印
 */
@Slf4j
public class WaterMarkUtils {

	/**
	 * 默认下载位置
	 */
	public static final String path = "F:/下载位置";

	/**
	 * 字体;
	 */
	public static final String FONTTYPE = "华文行楷";

	/**
	 * 字体样式;
	 */
	public static final Integer FONTSTYLE = Font.PLAIN;

	/**
	 * 字体大小;
	 */
	public static final Integer FONTSIZE = 30;

	/**
	 * 水印内容-文字;
	 */
	public static final String CONTENT = "王葛瑞";

	/**
	 * 间距;
	 */
	public static final int SPACING = 100;

	/**
	 * 行高;
	 */
	public static final int LINE_HEIGHT = 100;

	/**
	 * 字体宽度;
	 */
	public static final int FONT_WIDTH = 1;

	/**
	 * 高;
	 */
	public static final int HEIGHT = 3970;

	/**
	 * 长;
	 */
	public static final int WIDTH = 3100;

	/**
	 * 透明 0->1.0f，逐渐不透明; 图片建议0.4
	 */
	public static final Float ALPHA = 0.2f;

	/**
	 * 角度-字体倾斜度;
	 */
	public static final int TORADIANS = -30;

	/**
	 * 颜色;
	 */
	public static final Color COLOR = Color.BLACK;

	/**
	 * 起始位置 X轴;
	 */
	public static final Integer X = 0;

	/**
	 * 起始位置 Y轴;
	 */
	public static final Integer Y = 0;

	// ==================================== word字体=====================================
	private static final String fontName = "宋体";

	// 字体大小
	private static final String fontSize = "0.2pt";

	// 字体颜色
	private static final String fontColor = "#d0d0d0";

	// 一个字平均长度，单位pt，用于：计算文本占用的长度（文本总个数*单字长度）
	private static final Integer widthPerWord = 10;

	// 与顶部的间距
	private static Integer styleTop = 0;

	// 文本旋转角度
	private static final String styleRotation = "45";

	// 参考：https://blog.csdn.net/Ka__ze/article/details/131881795?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522169232084916800226537482%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=169232084916800226537482&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_ecpm_v1~times_rank-1-131881795-null-null.142^v93^insert_down1&utm_term=poi%E6%B7%BB%E5%8A%A0%E6%B0%B4%E5%8D%B0&spm=1018.2226.3001.4187

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		HttpServletResponse response = null;
		try {
			// 图片-保存到指定位置
			// markImg("I:/Desktop/图片/1.jpg", "I:/Desktop/图片/word/", response);
			// 图片-输出流返回
			// markImg("I:/Desktop/图片/1.jpg", "", response);
			// word
			// setWordWaterMark("I:/Desktop/图片/word/123.DOCX", "I:/Desktop/图片/word/");
			// PDF
			pdfAddWaterMark("F:/下载位置/pdf.pdf", "I:/Desktop/图片/word/");
			System.out.println(response);
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 为Excel打上水印工具函数 请自行确保参数值，以保证水印图片之间不会覆盖。 在计算水印的位置的时候，并没有考虑到单元格合并的情况，请注意
	 * @param wb Excel Workbook
	 * @param sheet 需要打水印的Excel
	 * @param bufferImg 水印地址，classPath，目前只支持png格式的图片，
	 * 因为非png格式的图片打到Excel上后可能会有图片变红的问题，且不容易做出透明效果。
	 * 同时请注意传入的地址格式，应该为类似："\\excelTemplate\\test.png"
	 * @param startXCol 水印起始列
	 * @param startYRow 水印起始行
	 * @param betweenXCol 水印横向之间间隔多少列
	 * @param betweenYRow 水印纵向之间间隔多少行
	 * @param XCount 横向共有水印多少个
	 * @param YCount 纵向共有水印多少个
	 * @param waterRemarkWidth 水印图片宽度为多少列
	 * @param waterRemarkHeight 水印图片高度为多少行
	 * @throws IOException
	 */
	public static void putWaterRemarkToExcel(Workbook wb, Sheet sheet, BufferedImage bufferImg, int startXCol,
			int startYRow, int betweenXCol, int betweenYRow, int XCount, int YCount, int waterRemarkWidth,
			int waterRemarkHeight) throws IOException {

		// 导出到字节流B
		ByteArrayOutputStream os = new ByteArrayOutputStream();
		ImageIO.write(bufferImg, "png", os);
		// 加载图片
		// 开始打水印
		Drawing drawing = sheet.createDrawingPatriarch();

		// 按照共需打印多少行水印进行循环
		for (int yCount = 0; yCount < YCount; yCount++) {
			// 按照每行需要打印多少个水印进行循环
			for (int xCount = 0; xCount < XCount; xCount++) {
				// 创建水印图片位置
				int xIndexInteger = startXCol + (xCount * waterRemarkWidth) + (xCount * betweenXCol);
				int yIndexInteger = startYRow + (yCount * waterRemarkHeight) + (yCount * betweenYRow);
				/*
				 * 参数定义： 第一个参数是（x轴的开始节点）； 第二个参数是（是y轴的开始节点）； 第三个参数是（是x轴的结束节点）；
				 * 第四个参数是（是y轴的结束节点）； 第五个参数是（是从Excel的第几列开始插入图片，从0开始计数）；
				 * 第六个参数是（是从excel的第几行开始插入图片，从0开始计数）； 第七个参数是（图片宽度，共多少列）； 第8个参数是（图片高度，共多少行）；
				 */
				ClientAnchor anchor = drawing.createAnchor(0, 0, 0, 0, xIndexInteger, yIndexInteger,
						xIndexInteger + waterRemarkWidth, yIndexInteger + waterRemarkHeight);

				Picture pic = drawing.createPicture(anchor, wb.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG));
				pic.resize();
			}
		}
	}

	/**
	 * excel设置水印
	 * @param file
	 * @param markStr
	 */
	public static void setExcelWaterMark(File file, String markStr, String type) {
		try {
			FontImage.Watermark watermark = new FontImage.Watermark();
			watermark.setText("水印测试");
			BufferedImage image = FontImage.createWatermarkImage(null);
			if (type.equals("xlsx")) {
				XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(file));

				// 获取excel sheet个数
				int sheets = workbook.getNumberOfSheets();
				// 循环sheet给每个sheet添加水印
				for (int i = 0; i < sheets; i++) {
					XSSFSheet sheet = workbook.getSheetAt(i);
					// 导出到字节流B
					ByteArrayOutputStream os = new ByteArrayOutputStream();
					ImageIO.write(image, "png", os);

					int pictureIdx = workbook.addPicture(os.toByteArray(), Workbook.PICTURE_TYPE_PNG);
					// add relation from sheet to the picture data
					String rID = sheet.addRelation(null, XSSFRelation.IMAGES, workbook.getAllPictures().get(pictureIdx))
							.getRelationship().getId();
					// set background picture to sheet
					sheet.getCTWorksheet().addNewPicture().setId(rID);
				}
				// 保存位置
				String downloadPath = "I:/Desktop/图片/word/" + System.currentTimeMillis() + "_"
						+ StrUtil.subAfter("I:/Desktop/图片/word/1111.XLSX", "/", true);

				// 生成输出文件
				File file11 = new File(downloadPath);
				file11.createNewFile();
				workbook.write(new FileOutputStream(file11));
				workbook.close();

			}
			else {
				HSSFWorkbook wb = new HSSFWorkbook(new FileInputStream(file));
				// 获取excel sheet个数
				int sheets = wb.getNumberOfSheets();
				// 循环sheet给每个sheet添加水印
				for (int i = 0; i < sheets; i++) {
					Sheet sheet = wb.getSheetAt(i);
					putWaterRemarkToExcel(wb, sheet, image, 0, 0, 6, 10, 10, 10, 0, 0);
				}
				// 保存位置
				String downloadPath = "I:/Desktop/图片/word/" + System.currentTimeMillis() + "_"
						+ StrUtil.subAfter("I:/Desktop/图片/word/1111.XLSX", "/", true);

				// 生成输出文件
				File file11 = new File(downloadPath);
				file11.createNewFile();
				wb.write(new FileOutputStream(file11));
				wb.close();
			}

		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * word
	 * @param inputPath
	 * @param outPath
	 * @throws IOException
	 */
	private static void setWordWaterMark(String inputPath, String outPath) throws IOException {
		File file = new File(inputPath);
		XWPFDocument doc = new XWPFDocument(new FileInputStream(file));
		// 配置水印信息
		waterMarkDocXDocument(doc, CONTENT);
		// 保存位置
		String downloadPath = outPath + System.currentTimeMillis() + "_" + StrUtil.subAfter(inputPath, "/", true);

		// 生成输出文件
		File file11 = new File(downloadPath);
		file11.createNewFile();
		doc.write(new FileOutputStream(file11));
		doc.close();

	}

	/**
	 * word文字水印
	 * @param inputPath
	 * @param outPath
	 * @param markStr 水印名称
	 */
	public static void setWordWaterMark11(String inputPath, String outPath, String markStr) throws Exception {

		File inputFile = new File(inputPath);
		XWPFDocument doc = null;

		try {
			doc = new XWPFDocument(new FileInputStream(inputFile));
		}
		catch (FileNotFoundException var24) {
			throw new RuntimeException("源文件不存在");
		}
		catch (IOException var25) {
			throw new RuntimeException("读取源文件IO异常");
		}
		catch (Exception var26) {
			throw new RuntimeException("不支持的文档格式");
		}
		XWPFParagraph paragraph = doc.createParagraph();
		// 使用自带工具类完成水印填充
		XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
		if (headerFooterPolicy == null)
			headerFooterPolicy = doc.createHeaderFooterPolicy();
		headerFooterPolicy.createWatermark(markStr);
		// 设置文档只读
		doc.enforceReadonlyProtection();
		// 配置水印
		XWPFHeader header = headerFooterPolicy.getHeader(XWPFHeaderFooterPolicy.DEFAULT);
		paragraph = header.getParagraphArray(0);
		XmlObject[] xmlobjects = paragraph.getCTP().getRArray(0).getPictArray(0)
				.selectChildren(new javax.xml.namespace.QName("urn:schemas-microsoft-com:vml", "shape"));
		if (xmlobjects.length > 0) {
			com.microsoft.schemas.vml.CTShape ctshape = (com.microsoft.schemas.vml.CTShape) xmlobjects[0];
			ctshape.setFillcolor("#CC00FF");
			ctshape.setStyle(ctshape.getStyle() + ";rotation:315");
		}
		// 保存位置
		String downloadPath = outPath + System.currentTimeMillis() + "_" + StrUtil.subAfter(inputPath, "/", true);
		// 生成输出文件
		File file = new File(downloadPath);
		if (!file.exists()) {
			try {
				file.createNewFile();
			}
			catch (IOException e) {
				e.printStackTrace();
			}
		}
		try {
			doc.write(new FileOutputStream(file));
			doc.close();
		}
		catch (FileNotFoundException e) {
			e.printStackTrace();
		}
		catch (IOException e) {
			e.printStackTrace();
		}

		// ===== 输出流 和上面没关系=======================================================
		// 打开输出流，将doc写入输出文件
		OutputStream os = null;
		try {
			os = new FileOutputStream(file);
			doc.write(os);
		}
		catch (FileNotFoundException var21) {
			throw new RuntimeException("创建输出文件失败");
		}
		catch (Exception var22) {
			throw new RuntimeException("添加文档水印失败");
		}
		finally {
			if (os != null) {
				try {
					os.close();
				}
				catch (IOException var20) {
					var20.printStackTrace();
				}
			}
		}

	}

	/**
	 * word添加水印
	 * @param inputPath
	 * @param outPath
	 * @param markStr
	 */
	// public static void addWordWaterMark(String inputPath, String outPath, String
	// markStr) {
	// // 读取原始文件
	// File inputFile = new File(inputPath);
	// XWPFDocument doc = null;
	// try {
	// doc = new XWPFDocument(new FileInputStream(inputFile));
	// } catch (FileNotFoundException var24) {
	// throw new RuntimeException("源文件不存在");
	// } catch (IOException var25) {
	// throw new RuntimeException("读取源文件IO异常");
	// } catch (Exception var26) {
	// throw new RuntimeException("不支持的文档格式");
	// }
	// // 使用自带工具类完成水印填充
	// XWPFHeaderFooterPolicy headerFooterPolicy = doc.getHeaderFooterPolicy();
	// headerFooterPolicy.createWatermark(markStr);
	// // 设置文档只读
	// doc.enforceReadonlyProtection();
	// // 生成输出文件
	// File file = new File(outPath);
	// if (!file.exists()) {
	// try {
	// file.createNewFile();
	// } catch (IOException var23) {
	// throw new RuntimeException("创建输出文件失败");
	// }
	// }
	// // 打开输出流，将doc写入输出文件
	// OutputStream os = null;
	// try {
	// os = new FileOutputStream(outPath);
	// doc.write(os);
	// } catch (FileNotFoundException var21) {
	// throw new RuntimeException("创建输出文件失败");
	// } catch (Exception var22) {
	// throw new RuntimeException("添加文档水印失败");
	// } finally {
	// if (os != null) {
	// try {
	// os.close();
	// } catch (IOException var20) {
	// var20.printStackTrace();
	// }
	// }
	// }
	// }

	/**
	 * pdf文件添加水印，使用itextpdf，速度最快--测试
	 * @param filePath
	 * @param fileSavePath
	 * @return
	 */
	public static String pdfAddWaterMark(String filePath, String fileSavePath) throws Exception {
		PdfReader reader = new PdfReader(filePath);
		// 保存位置
		String downloadPath = fileSavePath + System.currentTimeMillis() + "_" + StrUtil.subAfter(filePath, "/", true);
		PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(downloadPath));
		PdfGState gs1 = new PdfGState();
		// 设置透明度
		gs1.setFillOpacity(ALPHA);
		// 得到水印图片
		String resizePath = resizeImage(filePath, fileSavePath);

		com.itextpdf.text.Image image = com.itextpdf.text.Image.getInstance(resizePath);

		// 获取PDF页数
		int num = reader.getNumberOfPages();
		com.itextpdf.text.Rectangle pagesize;
		float width = 0f;
		float height = 0f;
		int x = 0;
		for (int i = 1; i <= num; i++) {
			// 得到页面大小
			x++;
			if (x == 1) {
				pagesize = reader.getPageSize(i);
				width = pagesize.getWidth();
				height = pagesize.getHeight();
			}
			// 水印图片设置在内容之上，之下用getUnderContent
			PdfContentByte pdfContentByte = stamper.getOverContent(i);
			pdfContentByte.setGState(gs1);
			// 设置图片的位置，参数Image.UNDERLYING是作为文字的背景显示。
			image.setAlignment(com.itextpdf.text.Image.UNDERLYING);
			// 设置图片的绝对位置
			image.setAbsolutePosition((width - image.getWidth()) / 2, (height - image.getHeight()) / 2);

			pdfContentByte.addImage(image);
		}
		stamper.close();
		reader.close();

		// 删除缩放后的图片
		FileUtil.del(resizePath);

		return downloadPath;
	}

	/**
	 * 图片添加水印
	 * @param srcImgPath 需要添加水印的图片的路径
	 * @param outImgPath 添加水印后图片输出路径
	 */
	public static String markImg(String srcImgPath, String outImgPath, HttpServletResponse response) throws Exception {
		try {
			if (StrUtil.isBlank(srcImgPath)) {
				return "文件已被删除";
			}
			// 保存位置
			String downloadPath = null;

			if (!StrUtil.isBlank(outImgPath)) {
				// 生成水印->保存图片到指定位置
				downloadPath = resizeImage(srcImgPath, outImgPath);

			}
			else {
				// 生成水印->保存图片到指定位置
				downloadPath = resizeImage(srcImgPath, outImgPath);
				// 输出流
				fileView(downloadPath, response);

			}
			return downloadPath;

		}
		catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	// -----------------------------------------------------公共项------------------------------------------------------------------------

	/**
	 * 判断类型
	 * @param filePath
	 * @return
	 */
	private static String getFileType(String filePath) {
		int i = filePath.lastIndexOf(".");
		String str = filePath.substring(i + 1);
		if (str.equals(TYPE.DOC.getName()) || str.equals(TYPE.DOCX.getName())) {
			return TYPE.WORD.getName();
		}
		else if (str.equals(TYPE.XLS.getName()) || str.equals(TYPE.XLSX.getName())) {
			return TYPE.EXCEL.getName();
		}
		else if (str.equals(TYPE.PPT.getName()) || str.equals(TYPE.PPTX.getName())) {
			return TYPE.PPT.getName();
		}
		else if (str.equals(TYPE.PDF.getName())) {
			return TYPE.PDF.getName();
		}
		else if (str.equals(TYPE.BMP.getName()) || str.equals(TYPE.GIF.getName()) || str.equals(TYPE.JPG.getName())
				|| str.equals(TYPE.JPEG.getName()) || str.equals(TYPE.PNG.getName())) {
			return TYPE.IMG.getName();
		}
		return "";

	}

	/**
	 * 生成水印图片
	 * @param filePath 保存位置
	 * @param outImgPath
	 * @return
	 * @throws Exception
	 */
	public static String resizeImage(String filePath, String outImgPath) throws Exception {

		// 名称水印及尺寸
		BufferedImage image = createWaterMark(CONTENT, WIDTH, HEIGHT);
		// 设置水印图片尺寸
		Image i = image.getScaledInstance(WIDTH, HEIGHT, Image.SCALE_SMOOTH);
		// 保存图片
		String downloadPath = outImgPath + System.currentTimeMillis() + "_" + StrUtil.subAfter(filePath, "/", true);

		if (TYPE.IMG.getName().equals(getFileType(filePath))) {
			// 获取画布
			BufferedImage read = ImageIO.read(new File(filePath));
			Graphics2D graphics = read.createGraphics();

			// 设置透明度,0->1,逐渐不透明
			graphics.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, ALPHA));
			// 添加水印并全覆盖
			graphics.drawImage(i, 0, 0, null);

			// 释放资源
			graphics.dispose();

			ImageIO.write(read, filePath.substring(filePath.lastIndexOf(".") + 1), new File(downloadPath));
		}
		else {
			ImageIO.write(image, "png", new File(downloadPath));
		}

		return downloadPath;

	}

	/**
	 * 满屏幕加水印
	 * @param content
	 * @param width
	 * @param height
	 * @return
	 */
	private static BufferedImage createWaterMark(String content, Integer width, Integer height) {
		BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);// 获取bufferedImage对象
		Font font = new Font(FONTTYPE, FONTSTYLE, FONTSIZE);
		Graphics2D g2d = image.createGraphics(); // 获取Graphics2d对象
		image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT);
		g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER));
		g2d.dispose();
		// 水印颜色
		Color markColor = COLOR;
		// 自适应颜色
		if (ObjectUtils.isEmpty(COLOR)) {
			markColor = getMarkColor(image, width, height);
		}

		for (int i = 1; i <= width / 10; i += 2) {
			for (int j = 1; j <= height / 10; j += 2) {
				int px = j * SPACING;
				int py = i * LINE_HEIGHT;
				g2d = image.createGraphics();
				g2d.setColor(markColor);
				g2d.setStroke(new BasicStroke(FONT_WIDTH)); // 设置字体
				g2d.setFont(font); // 设置字体类型 加粗 大小
				g2d.translate(px, py);// 设置原点
				g2d.rotate(Math.toRadians(TORADIANS));// 设置倾斜度
				FontRenderContext context = g2d.getFontRenderContext();
				Rectangle2D bounds = font.getStringBounds(content, context);
				g2d.drawString(content, X, Y);
				g2d.dispose();
			}
		}
		return image;
	}

	/**
	 * 水印-自适应图片颜色
	 * @param bi 水印画笔
	 * @param w 宽度
	 * @param h 高度
	 * @return
	 */
	public static Color getMarkColor(BufferedImage bi, int w, int h) {
		long sumR = 0;
		long sumG = 0;
		long sumB = 0;
		for (int x = 0; x < w; x++) {
			for (int y = 0; y < h; y++) {
				Color pixel = new Color(bi.getRGB(x, y));
				sumR += pixel.getRed();
				sumG += pixel.getGreen();
				sumB += pixel.getBlue();
			}
		}
		int num = w * h;
		int markColor = (int) (sumR / num + sumG / num + sumB / num) / 3;
		int halfRgb = 128;
		if (markColor < halfRgb) {
			markColor = markColor - 50 < 0 ? markColor + 50 : markColor - 50;
		}
		else {
			markColor = markColor + 50 > 255 ? markColor - 50 : markColor + 50;
		}
		return new Color(markColor, markColor, markColor, 100);
	}

	/**
	 * 以IO流的形式返回给前端
	 * @param fileUrl 文件路径
	 * @param response resp
	 */
	public static void fileView(String fileUrl, HttpServletResponse response) throws Exception {
		// 读取文件名 例：yyds.jpg
		String fileName = fileUrl.substring(fileUrl.lastIndexOf("/") + 1);
		// 流
		FileInputStream inputStream = new FileInputStream(fileUrl);
		OutputStream outputStream = response.getOutputStream();
		try {
			byte[] data = new byte[1024];
			// 全文件类型（传什么文件返回什么文件流）
			response.setContentType("application/x-msdownload");
			response.setHeader("Content-Disposition", "attachment; filename=\"" + fileName + "\"");
			response.setHeader("Accept-Ranges", "bytes");
			int read;
			while ((read = inputStream.read(data)) != -1) {
				outputStream.write(data, 0, read);
			}
			// 将缓存区数据进行输出
			outputStream.flush();
		}
		catch (IOException e) {
			log.error("失败", e);
			throw new Exception("exception");
		}
		finally {

			try {
				if (outputStream != null) {
					outputStream.close();
				}
			}
			catch (IOException e) {
				log.error("-----readImageView---input close--" + fileName + "--e:" + e);
			}
			try {
				if (inputStream != null) {
					inputStream.close();
				}
			}
			catch (IOException e) {
				log.error("-----readImageView---out close--" + fileName + "--e:" + e);
			}
		}
	}

	/**
	 * 给文档添加水印 此方法可以单独使用
	 * @param doc
	 * @param customText
	 */
	public static void waterMarkDocXDocument(XWPFDocument doc, String customText) {
		// 把整页都打上水印
		for (int lineIndex = -5; lineIndex < 20; lineIndex++) {
			styleTop = 100 * lineIndex;
			waterMarkDocXDocument_0(doc, customText);
		}
	}

	/**
	 * 为文档添加水印
	 * @param doc 需要被处理的docx文档对象
	 * @param customText 需要添加的水印文字
	 */
	public static void waterMarkDocXDocument_0(XWPFDocument doc, String customText) {
		// 水印文字之间使用8个空格分隔
		customText = customText + repeatString(" ", 8);
		// 一行水印重复水印文字次数
		customText = repeatString(customText, 10);
		// 如果之前已经创建过 DEFAULT 的Header，将会复用
		XWPFHeader header = doc.createHeader(HeaderFooterType.DEFAULT);
		int size = header.getParagraphs().size();
		if (size == 0) {
			header.createParagraph();
		}
		CTP ctp = header.getParagraphArray(0).getCTP();
		byte[] rsidr = doc.getDocument().getBody().getPArray(0).getRsidR();
		byte[] rsidrdefault = doc.getDocument().getBody().getPArray(0).getRsidRDefault();
		ctp.setRsidP(rsidr);
		ctp.setRsidRDefault(rsidrdefault);
		CTPPr ppr = ctp.addNewPPr();
		ppr.addNewPStyle().setVal("Header");
		// 开始加水印
		CTR ctr = ctp.addNewR();
		CTRPr ctrpr = ctr.addNewRPr();
		ctrpr.addNewNoProof();
		CTGroup group = CTGroup.Factory.newInstance();
		CTShapetype shapetype = group.addNewShapetype();
		CTTextPath shapeTypeTextPath = shapetype.addNewTextpath();
		shapeTypeTextPath.setOn(STTrueFalse.T);
		shapeTypeTextPath.setFitshape(STTrueFalse.T);
		CTLock lock = shapetype.addNewLock();
		lock.setExt(STExt.VIEW);
		CTShape shape = group.addNewShape();
		shape.setId("PowerPlusWaterMarkObject");
		shape.setSpid("_x0000_s102");
		shape.setType("#_x0000_t136");
		// 设置形状样式（旋转，位置，相对路径等参数）
		shape.setStyle(getShapeStyle(customText));
		shape.setFillcolor(fontColor);
		// 字体设置为实心
		shape.setStroked(STTrueFalse.FALSE);
		// 绘制文本的路径
		CTTextPath shapeTextPath = shape.addNewTextpath();
		// 设置文本字体与大小
		shapeTextPath.setStyle("font-family:" + fontName + ";font-size:" + fontSize);
		shapeTextPath.setString(customText);
		CTPicture pict = ctr.addNewPict();
		pict.set(group);
	}

	/**
	 * 将指定的字符串重复repeats次.
	 */
	private static String repeatString(String pattern, int repeats) {
		StringBuilder buffer = new StringBuilder(pattern.length() * repeats);
		Stream.generate(() -> pattern).limit(repeats).forEach(buffer::append);
		return new String(buffer);
	}

	/**
	 * 构建Shape的样式参数
	 * @param customText
	 * @return
	 */
	private static String getShapeStyle(String customText) {
		StringBuilder sb = new StringBuilder();
		// 文本path绘制的定位方式
		sb.append("position: ").append("absolute");
		// 计算文本占用的长度（文本总个数*单字长度）
		sb.append(";width: ").append(customText.length() * widthPerWord).append("pt");
		// 字体高度
		sb.append(";height: ").append("20pt");
		sb.append(";z-index: ").append("-251654144");
		sb.append(";mso-wrap-edited: ").append("f");
		// 设置水印的间隔，这是一个大坑，不能用top,必须要margin-top。
		sb.append(";margin-top: ").append(styleTop);
		sb.append(";mso-position-horizontal-relative: ").append("page");
		sb.append(";mso-position-vertical-relative: ").append("page");
		sb.append(";mso-position-vertical: ").append("left");
		sb.append(";mso-position-horizontal: ").append("center");
		sb.append(";rotation: ").append(styleRotation);
		return sb.toString();
	}

}
